// 是否字符串
function isString(obj) {
  return Object.prototype.toString.call(obj) === '[object String]'
}
// 是否对象
function isObject(obj) {
  return Object.prototype.toString.call(obj) === '[object Object]'
}
// 是否HTML元素
function isHtmlElement(node) {
  return node && node.nodeType === Node.ELEMENT_NODE
}
// 是否函数
function isFunction(functionToCheck) {
  var getType = {}
  return (
    functionToCheck &&
    getType.toString.call(functionToCheck) === '[object Function]'
  )
}
// 是否undefined
function isUndefined(val) {
  return val === void 0
}
// 判断对象是否相等[非严格]
function looseEqual(a, b) {
  const isObjectA = isObject(a)
  const isObjectB = isObject(b)
  if (isObjectA && isObjectB) {
    return JSON.stringify(a) === JSON.stringify(b)
  } else if (!isObjectA && !isObjectB) {
    return String(a) === String(b)
  } else {
    return false
  }
}
// 判断数组是否相等
function arrayEquals(arrayA, arrayB) {
  arrayA = arrayA || []
  arrayB = arrayB || []

  if (arrayA.length !== arrayB.length) {
    return false
  }

  for (let i = 0; i < arrayA.length; i++) {
    if (!looseEqual(arrayA[i], arrayB[i])) {
      return false
    }
  }

  return true
}
// 判断是否相等
function isEqual(value1, value2) {
  if (Array.isArray(value1) && Array.isArray(value2)) {
    return arrayEquals(value1, value2)
  }
  return looseEqual(value1, value2)
}
// 是否为空
function isEmpty(val) {
  // null or undefined
  if (val == null) return true

  if (typeof val === 'boolean') return false

  if (typeof val === 'number') return !val

  if (val instanceof Error) return val.message === ''

  switch (Object.prototype.toString.call(val)) {
    // String or Array
    case '[object String]':
    case '[object Array]':
      return !val.length

    // Map or Set or File
    case '[object File]':
    case '[object Map]':
    case '[object Set]': {
      return !val.size
    }
    // Plain Object
    case '[object Object]': {
      return !Object.keys(val).length
    }
  }

  return false
}

// 是否手机号码
function isTel(tel) {
  return /^1[3-9]\d{9}$/.test(String(tel))
}
// 是否邮箱
function isEmail(email) {
  return /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/.test(
    String(email)
  )
}
// 是否为整数 含正整数, 负整数, 0
function isInteger(number) {
  return /^-?\d+$/.test(String(number))
}
// 是否正整数，正浮点数和0（常用于商品价格验证）
function isPrice(number) {
  return /^\d+(\.\d+)?$/.test(String(number))
}
// 是否实数
function isReal(number) {
  return /^(-?\d+)(\.\d+)?$/.test(String(number))
}
// 是否汉字
function isChinese(content) {
  return /^[\u2E80-\u9FFF]+$/.test(content)
}
// 是否身份证号码
function isIDCard(a) {
  a = a.toUpperCase()
  for (
    var b = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2],
      c = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'],
      d = a + '',
      e = a[17],
      f = d.substring(0, 17),
      g = f.split(''),
      h = g.length,
      j = 0,
      k = 0;
    k < h;
    k++
  )
    j += g[k] * b[k]
  var l = j % 11,
    m = c[l],
    n =
      /^[1-9][0-9]{5}([1][9][0-9]{2}|[2][0][0|1][0-9])([0][1-9]|[1][0|1|2])([0][1-9]|[1|2][0-9]|[3][0|1])[0-9]{3}([0-9]|[Xx])$/,
    o = n.test(a)
  return e === m && o
}
/**
 * 密码强度正则
 * 最少6位，包括至少1个大写字母，1个小写字母，1个数字，1个特殊字符
 */
function passwordStrong(v) {
  return /^.*(?=.{6,})(?=.*\d)(?=.*[A-Z])(?=.*[a-z])(?=.*[!@#$%^&*? ]).*$/.test(
    String(v)
  )
}

module.exports = {
  isString,
  isObject,
  isHtmlElement,
  isFunction,
  isUndefined,
  looseEqual,
  arrayEquals,
  isEqual,
  isEmpty,
  isTel,
  isEmail,
  isInteger,
  isPrice,
  isReal,
  isChinese,
  isIDCard,
  passwordStrong
}
